package com.hoki.zj.hrm.config;

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

import static com.hoki.zj.hrm.constant.MQMessageConst.*;

@Configuration
public class MQConfig {

    /**
     * 创建死信交换机
     *  指定类型
     *  指定名字
     * @return Exchange
     */
    @Bean
    public Exchange createExchange() {
        return ExchangeBuilder.topicExchange(EXCHANGE_NAME_DEAD).build();
    }

    /**
     * 创建延迟队列,默认持久
     * @return Queue
     */
    @Bean
    public Queue createDelayQueue() {
        Map<String,Object> map = new HashMap<>();
        map.put("x-dead-letter-exchange", EXCHANGE_NAME_DEAD);    //过期的消息给哪个交换机的名字
        map.put("x-dead-letter-routing-key", "order.dead");   //死信交换机把消息个哪个个routingkey
        map.put("x-message-ttl", 60000);    //队列过期时间300000s:5分钟
        return new Queue(QUEUE_NAME_DELAY,
                true,false,false,map);
    }

    /**
     * 创建死信队列,默认持久
     * @return Queue
     */
    @Bean
    public Queue createDeadQueue() {
        return new Queue(QUEUE_NAME_DEAD);
    }

    /**
     * 绑定订单队列
     * @return Binding
     */
    @Bean
    public Binding bindDelayQueue() {
        return BindingBuilder.bind(createDelayQueue()). // 指定绑定的队列
                to(createExchange()). // 指定绑定的交换机
                with("#.delay"). // 指定绑定的路由
                noargs(); // 无额外参数
    }

    /**
     * 绑定订单队列
     * @return Binding
     */
    @Bean
    public Binding bindDeadQueue() {
        return BindingBuilder.bind(createDeadQueue()). // 指定绑定的队列
                to(createExchange()). // 指定绑定的交换机
                with("#.dead"). // 指定绑定的路由
                noargs(); // 无额外参数
    }

    /**
     * 配置json转换器
     * @param connectionFactory 连接工厂
     * @return RabbitTemplate
     */
    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
        rabbitTemplate.setMandatory(true);
        return rabbitTemplate;
    }

    /**
     * 消费者转化器(监听容器工厂)
     * @param connectionFactory 连接工厂
     * @return RabbitListenerContainerFactory
     */
    @Bean("rabbitListenerContainerFactory")
    public RabbitListenerContainerFactory<?> rabbitListenerContainerFactory(ConnectionFactory connectionFactory){
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setMessageConverter(new Jackson2JsonMessageConverter());
        factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        factory.setPrefetchCount(1);
        return factory;
    }

}
